package com.fishing.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonUtils {  
	  
    private final static ObjectMapper objectMapper = new ObjectMapper();  
  
    private JsonUtils() {  
  
    }  
  
    public static ObjectMapper getInstance() {  
  
        return objectMapper;  
    }  
  
    /** 
     * javaBean,list,array convert to json string 
     */  
    public static String obj2json(Object obj) throws Exception {  
        return objectMapper.writeValueAsString(obj);  
    }  
  
    /** 
     * json string convert to javaBean 
     */  
    public static <T> T json2pojo(String jsonStr, Class<T> clazz)  
            throws Exception {  
        return objectMapper.readValue(jsonStr, clazz);  
    }  
  
    /** 
     * json string convert to map 
     */  
    public static <T> Map<String, Object> json2map(String jsonStr)  
            throws Exception {  
        return objectMapper.readValue(jsonStr, Map.class);  
    }  
  
    /** 
     * json string convert to map with javaBean 
     */  
    public static <T> Map<String, T> json2map(String jsonStr, Class<T> clazz)  
            throws Exception {  
        Map<String, Map<String, Object>> map = objectMapper.readValue(jsonStr,  
                new TypeReference<Map<String, T>>() {  
                });  
        Map<String, T> result = new HashMap<String, T>();  
        for (Entry<String, Map<String, Object>> entry : map.entrySet()) {  
            result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));  
        }  
        return result;  
    }  
  
    /** 
     * json array string convert to list with javaBean 
     */  
    public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz)  
            throws Exception {  
        List<Map<String, Object>> list = objectMapper.readValue(jsonArrayStr,  
                new TypeReference<List<T>>() {  
                });  
        List<T> result = new ArrayList<T>();  
        for (Map<String, Object> map : list) {  
            result.add(map2pojo(map, clazz));  
        }  
        return result;  
    }  
  
    /** 
     * map convert to javaBean 
     */  
    public static <T> T map2pojo(Map map, Class<T> clazz) {  
        return objectMapper.convertValue(map, clazz);  
    }
    
    
    /**
	 * 对象转换为Map
	 */
	public static Map<String, Object> transBean2Map(Object obj) {
		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				if (!key.equals("class")) {
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);
					map.put(key, value);
				}
			}
		} catch (Exception e) {
			System.out.println("transBean2Map Error " + e);
		}
		return map;
	}

    
    /**
     * 按照JSONArray中的对象的某个字段进行排序(采用fastJson)
     * 
     * @param jsonArrStr
     *        json数组字符串
     * 
     */
    public static String jsonArraySort(String jsonArrStr) {
        JSONArray jsonArr = JSON.parseArray(jsonArrStr);//将json格式的数据转换成数组格式
        JSONArray sortedJsonArray = new JSONArray();
        List<JSONObject> jsonValues = new ArrayList<JSONObject>();
        for (int i = 0; i < jsonArr.size(); i++) {
            jsonValues.add(jsonArr.getJSONObject(i));
        }
        Collections.sort(jsonValues, new Comparator<JSONObject>() {  //进行数据排序，但是要可比较的
            // You can change "Name" with "ID" if you want to sort by ID
            private static final String KEY_NAME = "Name";

            @Override
            public int compare(JSONObject a, JSONObject b) {
                String valA = new String();
                String valB = new String();
                try {
                    // 这里是a、b需要处理的业务，需要根据你的规则进行修改。
                    String aStr = a.getString(KEY_NAME);
                    valA = aStr.replaceAll("-", "");//把字符串某些字符全部替换成别的,前面是正则表达式
                    String bStr = b.getString(KEY_NAME);
                    valB = bStr.replaceAll("-", "");
                } catch (JSONException e) {
                    // do something
                }
                return -valA.compareTo(valB); //用于两个相同数据类型的比较，两个不同类型的数据不能用此方法来比较  相同返回0  小于参数返回 -1  大于参数返回1
                // if you want to change the sort order, simply use the following:
                // return -valA.compareTo(valB);
            }
        });
        for (int i = 0; i < jsonArr.size(); i++) {
            sortedJsonArray.add(jsonValues.get(i));
        }
        return sortedJsonArray.toString();
    }
    
    /**
     * Json排序,未完善
     * */
    public static <T> String fromList(List<T> list) throws Exception{
    	//创建JSONObject
    	JSONArray jsonArray = new JSONArray();
    	for (T t : list) {
    		JSONObject jo = new JSONObject(new LinkedHashMap<>());
    		//通过反射获得类中的成员变量们
    		Field[] fields = t.getClass().getDeclaredFields();
    		for (Field field : fields) {
    			String Lname = field.getName();
    			//通过反射获得get方法
    			Method method = t.getClass().getMethod("get" + Lname);
    			//通过get方法获得值
    			Object value = method.invoke(t);
    			jo.put(Lname, value);
    		}
    		jsonArray.add(jo);
    	}
    	return jsonArray.toJSONString();
    }

    public static <T> String fromList(List<T> list , String[] exclusions) throws Exception{
    	JSONArray jsonArray = new JSONArray();
    	for (T t : list) {
    		JSONObject jo = new JSONObject(new LinkedHashMap<>());
    		Field[] fields = t.getClass().getDeclaredFields();
    		for (Field field : fields) {
    			for (String s : exclusions) {
    				String Lname = field.getName();
    				if(s.equals(Lname)){
    					//该属性名需要排除
    					break;
    				}else {
    					//该属性名无需排除，添加进jsonObject中
    					Method method = t.getClass().getMethod("get" + Lname);
    					Object value = method.invoke(t);
    					jo.put(Lname, value);
    				}
    			}
    		}
    		jsonArray.add(jo);
    	}
    	return jsonArray.toJSONString();
    }
}  